﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

/**
 * THÊM
 * 2013-07-30
 * AnhTran
 **/
using DirectX.Capture;
using DShowNET;
using System.Threading;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;

namespace ImageProcessToolbox
{
    public partial class frmCameraViewer : Form
    {
        #region Các biến liên quan đến hình ảnh của DirectX.Capture và DShowNET
        private Source current;
        int c = 0;
        private Filters filters;
        public string nameDevice;
        public DirectX.Capture.Capture capture = null;
        public DirectX.Capture.Filter videoDevice = null;
        #endregion

        private Emgu.CV.Capture _captureEmgu = null;
        private bool _captureEmguInProgress;
        private int camIndex = 0;

        private Image<Rgb, Byte> result;

        public Image<Rgb, Byte> Result
        {
            get { return result; }
        }

        /// <summary>
        /// 2013-07-25
        /// Last edit AnhTran
        /// Các khởi tạo cần thiết để sử dụng camera analog
        /// </summary>
        private void KhoiTaoVideoDirectXCapture()
        {
            #region anh tran: KhoiTaoVideoDirectXCapture
            try
            {
                //Tìm kiếm các thiết bị video hiện có trên máy
                try
                {
                    filters = new Filters();
                    CameraListStripComboBox.Items.Clear();
                    for (c = 0; c < filters.VideoInputDevices.Count; c++)
                    {
                        //Sẽ chỉnh sửa lại tùy ứng dụng
                        //Cập nhật danh sách thiết bị lên menu
                        CameraListStripComboBox.Items.Add(filters.VideoInputDevices[c].Name);
                    }

                }
                catch (Exception ex)
                {
                    MessageBox.Show("Máy bạn không có thiết bị video\n" + ex.Message, "Lỗi phần cứng", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                // Tắt kết nối với camera nếu có
                try
                {
                    if (capture != null)
                    {
                        capture.Dispose();
                        Thread.Sleep(100);
                        capture.Stop();
                        Thread.Sleep(100);
                    }
                }
                catch
                {

                }

                // Chọn camera mặc định để sử dụng
                for (c = 0; c < filters.VideoInputDevices.Count; c++)
                {
                    videoDevice = filters.VideoInputDevices[c];
                    //SAU NÀY 1 PHẦN MỀM CHỈ CÓ 1 THIẾT BỊ
                    if (c == camIndex)
                    {
                        CameraListStripComboBox.SelectedIndex = camIndex;
                        break;
                    }
                }


                //Cấu hình các thông số cần thiết cho camera analog
                if ((videoDevice != null))
                {
                    capture = new DirectX.Capture.Capture(videoDevice, null, false);
                }
                if (this.capture != null)
                {
                    this.capture.AllowSampleGrabber = true;
                    this.capture.VideoSource = this.capture.VideoSource;
                    this.capture.UseVMR9 = false;
                }
                // Choose the video source
                // If the device only has one source, this menu item will be disabled
                capture.VideoSources = null;
                current = capture.VideoSource;
                for (c = 0; c < capture.VideoSources.Count; c++)
                {
                    if (capture.VideoSources[c].Name == "Video Composite")
                        current = capture.VideoSources[c];
                }
                if (current != null)
                {
                    capture.VideoSource = current;
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("Máy bạn không có thiết bị video\n" + ex.Message, "Lỗi phần cứng", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            #endregion
        }

        /// <summary>
        /// 2013-07-25
        /// Last edit AnhTran
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="arg"></param>
        private void ProcessFrame(object sender, EventArgs arg)
        {
            Image<Bgr, Byte> frame = _captureEmgu.RetrieveBgrFrame();
            //Xoa vien den canh phai-loi cua camera
            //Neu khong co vien den thi bo dong nay cung duoc
            //frame.ROI = new Rectangle(offsetWidth, offsetHeight, camWidth, camHeight);


            captureImageBox.Image = frame;
        }

        /// <summary>
        /// 2013-07-30
        /// AnhTran
        /// </summary>
        /// <param name="SelectedIndex"></param>
        public frmCameraViewer(int SelectedIndex)
        {
            InitializeComponent();
            camIndex = SelectedIndex;
        }

        /// <summary>
        /// 2013-07-30
        /// AnhTran
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmCameraViewer_Load(object sender, EventArgs e)
        {
            //Khởi tạo camera
            KhoiTaoVideoDirectXCapture();
            try
            {
                _captureEmgu = new Emgu.CV.Capture(camIndex);

                _captureEmgu.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, 480);
                _captureEmgu.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, 640);

                _captureEmgu.ImageGrabbed += ProcessFrame;

                result = null;
            }
            catch (NullReferenceException excpt)
            {
                MessageBox.Show(excpt.Message);
            }
        }

        /// <summary>
        /// 2013-07-30
        /// AnhTran
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnChupHinh_Click(object sender, EventArgs e)
        {
            if (_captureEmgu != null)
            {
                if (_captureEmguInProgress)
                {  //stop the capture
                    _captureEmgu.Pause();
                }
                else
                {
                    //start the capture
                    _captureEmgu.Start();
                }

                _captureEmguInProgress = !_captureEmguInProgress;
            }
        }

        /// <summary>
        /// 2013-07-30
        /// AnhTran
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmCameraViewer_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (capture != null)
            {
                capture.Dispose();
                Thread.Sleep(10);
                capture.Stop();
                Thread.Sleep(10);

            }

            if (_captureEmgu != null)
            {
                _captureEmgu.Dispose();
                Thread.Sleep(10);
                _captureEmgu.Stop();
                Thread.Sleep(10);

            }
        }

        /// <summary>
        /// 2013-07-30
        /// AnhTran
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLuuKetQua_Click(object sender, EventArgs e)
        {
            if (!_captureEmguInProgress)
            {
                try
                {
                    result = new Image<Rgb, byte>(captureImageBox.Image.Bitmap);
                    this.Close();
                }
                catch
                {
                }
            }
        }

        /// <summary>
        /// 2013-07-30
        /// AnhTran
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCauHinh_Click(object sender, EventArgs e)
        {
            capture.PropertyPages[0].Show(this);
        }
    }
}
